#include "stm32f10x.h"
#include <time.h>

uint16_t MyRTC_Time[] = { 2023, 12, 18, 11, 21, 59 };
int8_t MyRTC_TimeZone = 8;

void MyRTC_SetTime(void);

void MyRTC_Init(void) {
    // RCC
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    PWR_BackupAccessCmd(ENABLE);

    // 判断 BKP 是否完全断电过
    if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) {
        // 启用 外部LSE晶振
        RCC_LSEConfig(RCC_LSE_ON);
        while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
        // 设置 RTC 时钟源
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        RCC_RTCCLKCmd(ENABLE);

        // 等待同步
        RTC_WaitForSynchro();
        // 等待上一次写入操作完成
        RTC_WaitForLastTask();

        // 配置预分频器
        RTC_SetPrescaler(32767); // 32.768KHz，预分频包含0，所以要 -1
        RTC_WaitForLastTask();

        // 配置时钟
        // RTC_SetCounter(0);
        // RTC_WaitForLastTask();
        MyRTC_SetTime();

        BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
    }
    else {

        // 等待同步
        RTC_WaitForSynchro();
        // 等待上一次写入操作完成
        RTC_WaitForLastTask();
    }
}

void MyRTC_SetTime(void) {
    time_t time_cnt;
    struct tm time_date;
    time_date.tm_year = MyRTC_Time[0] - 1900;
    time_date.tm_mon = MyRTC_Time[1] - 1;
    time_date.tm_mday = MyRTC_Time[2];
    time_date.tm_hour = MyRTC_Time[3];
    time_date.tm_min = MyRTC_Time[4];
    time_date.tm_sec = MyRTC_Time[5];
    time_cnt = mktime(&time_date) - MyRTC_TimeZone * 3600;
    RTC_SetCounter(time_cnt);
    RTC_WaitForLastTask();
}

void MyRTC_GetTime(void) {
    time_t time_cnt;
    struct tm time_date;
    time_cnt = RTC_GetCounter() + MyRTC_TimeZone * 3600;
    RTC_WaitForLastTask();
    time_date = *localtime(&time_cnt);
    MyRTC_Time[0] = time_date.tm_year + 1900;
    MyRTC_Time[1] = time_date.tm_mon + 1;
    MyRTC_Time[2] = time_date.tm_mday;
    MyRTC_Time[3] = time_date.tm_hour;
    MyRTC_Time[4] = time_date.tm_min;
    MyRTC_Time[5] = time_date.tm_sec;
}
